﻿using System;
using System.Linq;
using System.Web;
using System.Web.Profile;
using System.Web.Security;
using System.Threading;

namespace FranceTriple.Dal
{
    public class UserProfile : ProfileBase
    {
        private String LastSeenFormat = "LastSeenFormat".ToLocalizedString();
        private String yearsLocalized = "years".ToLocalizedString();
        private String daysLocalized = "days".ToLocalizedString();
        private static String profilBattlelogFormat = @"http://battlelog.battlefield.com/bf3/user/{0}/";

        private DateTime newDateTime = new DateTime();

        public UserProfile() { }

        public static aspnet_Role AspNetRoleGetEntity(Guid RoleId)
        {
            aspnet_Role role;
            try
            {
                using (FranceTriple.Dal.Model1Container ctx = new Model1Container())
                {
                    role = (from r in ctx.aspnet_Roles
                            where (r.RoleId == RoleId)
                            select r).FirstOrDefault();
                }
            }
            catch (Exception ex)
            {
                LoggingManager.Logger.Log(LoggingCategory.Error, ex.Message);
                throw new DalException(String.Format("RetrieveError".ToLocalizedString(), "AspNetRoleGetEntity", ex.Message), ex) { EntityType = typeof(aspnet_Role) };
            }
            return role;
        }
        public static void ResetAllUsersNumberOfForumPost()
        {
            UserProfile[] users;
            UserProfile profile;
            users = new UserProfile().GetAllUserProfileArray();

            foreach (var user in users)
            {
                profile = UserProfile.GetUserProfile(user.UserName, true);
                profile.NumberOfForumPost = 0;
                profile.Save();
            }
        }
        public static void IncrementUserNumberOfForumPost(String Username)
        {
            UserProfile profile;
            profile = UserProfile.GetUserProfile(Username, true);
            if (profile != null)
            {
                profile.NumberOfForumPost++;
                profile.Save();
            }
            else
            {
                //"Utilisateur non reconnu: " + Username
                throw new DalException(String.Format("RetrieveError".ToLocalizedString(), "IncrementUserNumberOfForumPost", "Utilisateur non reconnu: " + HttpUtility.HtmlEncode(Username)), null) { EntityType = typeof(UserProfile) };
            }
        }
        public static UserProfile GetUserProfile()
        {
            UserProfile profile;
            try
            {
                profile = HttpContext.Current.Profile as UserProfile;
            }
            catch (Exception ex)
            {
                LoggingManager.Logger.Log(LoggingCategory.Error, ex.Message);
                throw new UserProfileException(String.Format("RetrieveError".ToLocalizedString(), "UserProfile", ex.Message), ex) { EntityType = typeof(UserProfile) };
            }
            return profile;
        }
        public static UserProfile GetUserProfile(string username)
        {
            UserProfile profile;
            try
            {
                profile = Create(username, true) as UserProfile;
            }
            catch (Exception ex)
            {
                LoggingManager.Logger.Log(LoggingCategory.Error, ex.Message);
                throw new UserProfileException(String.Format("RetrieveError".ToLocalizedString(), "UserProfile", ex.Message), ex) { EntityType = typeof(UserProfile) };
            }
            return profile;
        }
        public static UserProfile GetUserProfile(string username, bool isauthenticated)
        {
            UserProfile profile;
            try
            {
                profile = Create(username, isauthenticated) as UserProfile;
            }
            catch (Exception ex)
            {
                LoggingManager.Logger.Log(LoggingCategory.Error, ex.Message);
                throw new UserProfileException(String.Format("RetrieveError".ToLocalizedString(), "UserProfile", ex.Message), ex) { EntityType = typeof(UserProfile) };
            }
            return profile;
        }
        public UserProfile[] GetUserRoleProfileArray(String RoleName)
        {
            String[] userMember;
            UserProfile[] userProfile;
            Int32 i;

            userMember = Roles.GetUsersInRole(RoleName);
            userProfile = new UserProfile[userMember.Length];
            i = 0;
            foreach (string user in userMember)
            {
                userProfile[i++] = UserProfile.GetUserProfile(user);
            }
            return userProfile;
        }
        public MembershipUser[] GetUserRoleMembershipArray(String RoleName)
        {
            String[] userMember;
            MembershipUser[] userTab;
            Int32 i;
            userMember = Roles.GetUsersInRole(RoleName);
            userTab = new MembershipUser[userMember.Length];
            i = 0;
            foreach (string user in userMember)
            {
                userTab[i++] = Membership.GetUser(user, false);
            }
            return userTab;
        }
        public UserProfile[] GetAllUserProfileArray()
        {
            UserProfile[] userProfile;
            MembershipUserCollection userCol;
            Int32 i,userColCount;
            userCol = Membership.GetAllUsers();
            userColCount = userCol.Count;
            userProfile = new UserProfile[userColCount];
            i = 0;
            foreach (MembershipUser user in userCol)
            {
                userProfile[i++] = UserProfile.GetUserProfile(user.UserName, true);
            }
            return userProfile;
        }
        public MembershipUser[] GetAllMembershipUserArray()
        {
            MembershipUser[] userTab;
            MembershipUserCollection userCol;
            Int32 i, userColCount;
            userCol = Membership.GetAllUsers();
            userColCount = userCol.Count;
            userTab = new MembershipUser[userColCount];
            i = 0;
            foreach (MembershipUser user in userCol)
            {
                userTab[i++] = user;
            }
            return userTab;
        }
        public String[] GetLastUserVisit(Int32 MaximumNumberOfUsersToReturn)
        {
            String[] LastSeenUsers;
            try
            {
                LastSeenUsers = (from u in GetAllMembershipUserArray()
                                 orderby u.LastActivityDate descending
                                 select (u.UserName + " " + (DateTime.Now.Subtract(u.LastActivityDate)).ToString(LastSeenFormat))).Take(MaximumNumberOfUsersToReturn).ToArray();
            }
            catch (Exception ex)
            {
                LoggingManager.Logger.Log(LoggingCategory.Error, ex.Message);
                throw new UserProfileException(String.Format("RetrieveError".ToLocalizedString(), "String[]", ex.Message), ex) { EntityType = typeof(String[]) };
            }
            return LastSeenUsers;
        }
        public String[] GetTodayBirthday()
        {
            UserProfile[] userProfiles;
            String[] TodayBirthDay;
            try
            {
                userProfiles = new UserProfile().GetAllUserProfileArray();

                // L'ajout de 0 devant Joyeux Anniversaire est pour permettre la coloration de cette ligne sans utiliser le libellé.
                TodayBirthDay = (from u in userProfiles
                                 let NextBirthday = ((new DateTime(DateTime.Now.Year, u.UserBirthday.Month, u.UserBirthday.Day) < DateTime.Now) ? new DateTime(DateTime.Now.Year + 1, u.UserBirthday.Month, u.UserBirthday.Day) : new DateTime(DateTime.Now.Year, u.UserBirthday.Month, u.UserBirthday.Day)).Subtract(DateTime.Now).Days + 1
                                 let RemainingDays = (NextBirthday == 365) ? 0 : NextBirthday
                                 where u.UserBirthday != newDateTime && RemainingDays == 0
                                 orderby RemainingDays
                                 select u.UserName + " (" + (DateTime.Now.Year - u.UserBirthday.Year).ToString() + " " + yearsLocalized + ")").ToArray();
            }
            catch (Exception ex)
            {
                LoggingManager.Logger.Log(LoggingCategory.Error, ex.Message);
                throw new UserProfileException(String.Format("RetrieveError".ToLocalizedString(), "String[]", ex.Message), ex) { EntityType = typeof(String[]) };
            }
            return TodayBirthDay;
        }
        public String[] GetNextUserBirthday(Int32 MaximumNumberOfUsersToReturn)
        {
            UserProfile[] userProfiles;
            String[] NextUserBirthday;

            try
            {
                userProfiles = new UserProfile().GetAllUserProfileArray();

                // L'ajout de 0 devant Joyeux Anniversaire est pour permettre la coloration de cette ligne sans utiliser le libellé.
                NextUserBirthday = (from u in userProfiles
                                    let NextBirthday = ((new DateTime(DateTime.Now.Year, u.UserBirthday.Month, u.UserBirthday.Day) < DateTime.Now) ? new DateTime(DateTime.Now.Year + 1, u.UserBirthday.Month, u.UserBirthday.Day) : new DateTime(DateTime.Now.Year, u.UserBirthday.Month, u.UserBirthday.Day)).Subtract(DateTime.Now).Days + 1
                                    let RemainingDays = (NextBirthday == 365) ? 0 : NextBirthday
                                    where u.UserBirthday != newDateTime && RemainingDays > 0
                                    orderby RemainingDays
                                    select (String.Format("{0} {1}" + " " + daysLocalized, u.UserName, RemainingDays))).Take(MaximumNumberOfUsersToReturn).ToArray();
            }
            catch (Exception ex)
            {
                LoggingManager.Logger.Log(LoggingCategory.Error, ex.Message);
                throw new UserProfileException(String.Format("RetrieveError".ToLocalizedString(), "String[]", ex.Message), ex) { EntityType = typeof(String[]) };
            }
            return NextUserBirthday;
        }

        [SettingsAllowAnonymous(true)]
        public String UserChoosenCulture
        {
            get { return (string)base["UserChoosenCulture"]; }
            set { base["UserChoosenCulture"] = value; }
        }
        [SettingsAllowAnonymous(true)]
        public String UserTheme
        {
            get { return (string)base["UserTheme"]; }
            set { base["UserTheme"] = value; }
        }
        [SettingsAllowAnonymous(false)]
        public DateTime UserBirthday
        {
            get { return (DateTime)base["UserBirthday"]; }
            set { base["UserBirthday"] = value; }
        }
        [SettingsAllowAnonymous(false)]
        public String Bf3ColonelNickname
        {
            get { return (string)base["Bf3ColonelNickname"]; }
            set { base["Bf3ColonelNickname"] = value; }
        }
        [SettingsAllowAnonymous(false)]
        public Int32 TimePlayedToBecomeBf3Colonel
        {
            get { return (Int32)base["TimePlayedToBecomeBf3Colonel"]; }
            set { base["TimePlayedToBecomeBf3Colonel"] = value; }
        }
        [SettingsAllowAnonymous(false)]
        public Int32 Bf3ColonelDisplayOrder
        {
            get { return (Int32)base["Bf3ColonelDisplayOrder"]; }
            set { base["Bf3ColonelDisplayOrder"] = value; }
        }
        [SettingsAllowAnonymous(false)]
        public String UserGravatarEmail
        {
            get { return (string)base["UserGravatarEmail"]; }
            set { base["UserGravatarEmail"] = value; }
        }
        [SettingsAllowAnonymous(false)]
        public String UpperLabelSignature
        {
            get { return (string)base["UpperLabelSignature"]; }
            set { base["UpperLabelSignature"] = value; }
        }
        [SettingsAllowAnonymous(false)]
        public String ImageUrlSignature
        {
            get { return (string)base["ImageUrlSignature"]; }
            set { base["ImageUrlSignature"] = value; }
        }
        [SettingsAllowAnonymous(false)]
        public String NavigateUrlSignature
        {
            get { return (string)base["NavigateUrlSignature"]; }
            set { base["NavigateUrlSignature"] = value; }
        }
        [SettingsAllowAnonymous(false)]
        public String BottomLabelSignature
        {
            get { return (string)base["BottomLabelSignature"]; }
            set { base["BottomLabelSignature"] = value; }
        }
        [SettingsAllowAnonymous(false)]
        public Int32 Bf3Rank
        {
            get { return (Int32)base["Bf3Rank"]; }
            set { base["Bf3Rank"] = value; }
        }
        [SettingsAllowAnonymous(false)]
        public String Bf3Grade
        {
            get
            {
                return ("rank" + this.Bf3Rank.ToString()).ToBf3RankLocalizedString();
            }
        }
        [SettingsAllowAnonymous(false)]
        public String Bf3BattlelogProfilUrl
        {
            get
            {
                if (Bf3ColonelNickname != String.Empty)
                    return String.Format(profilBattlelogFormat, Bf3ColonelNickname);
                else
                    return "#";
            }
        }
        [SettingsAllowAnonymous(false)]
        public String Bf3BattlelogProfilLink
        {
            get
            {
                if (Bf3ColonelNickname != String.Empty)
                    return "<a class=\"DataValueText\" href=\"" + String.Format(profilBattlelogFormat, Bf3ColonelNickname) + "\" target=\"blank\">" + UserName + "</a>";
                else
                    return UserName;
            }
        }
        [SettingsAllowAnonymous(false)]
        public String Bf3RankImage
        {
             get
            {
                String _Bf3RankImage = String.Empty;

                if (this.Bf3Rank < 46)
                    _Bf3RankImage = "~/images/rankssmall/r" + this.Bf3Rank + ".png";
                else
                    _Bf3RankImage = "~/images/rankssmall/ss" + (this.Bf3Rank - 45).ToString() + ".png";

                return _Bf3RankImage;
            }

           //get
           // {
           //     String _Bf3RankImage = String.Empty;
           //     try
           //     {
           //         using (FranceTriple.Dal.Model1Container ctx = new Model1Container())
           //         {
           //             _Bf3RankImage = (from rankImageUrl in ctx.Bf3RankSmiliesSet
           //                              where rankImageUrl.Rank == this.Bf3Rank
           //                              select rankImageUrl.ImageUrl).FirstOrDefault().ToString();
           //         }
           //     }
           //     catch (Exception ex)
           //     {
           //         LoggingManager.Logger.Log(LoggingCategory.Error, ex.Message);
           //         throw new DalException(String.Format("RetrieveError".ToLocalizedString(), "Bf3RankImage", ex.Message), ex) { EntityType = typeof(Bf3RankSmilies) };
           //     }
           //     return _Bf3RankImage;
           // }
        }
        [SettingsAllowAnonymous(false)]
        public Int32 NumberOfForumPost
        {
            get { return (Int32)base["NumberOfForumPost"]; }
            set { base["NumberOfForumPost"] = value; }
        }
        [SettingsAllowAnonymous(false)]
        public String Location
        {
            get { return (String)base["Location"]; }
            set { base["Location"] = value; }
        }
        [SettingsAllowAnonymous(false)]
        public String TimeZone
        {
            get
            {
                return ((String)base["TimeZone"] == String.Empty ?
                    "Romance Standard Time" :
                    (String)base["TimeZone"]);
            }
            set { base["TimeZone"] = value; }
        }
        [SettingsAllowAnonymous(false)]
        public String InitialAddressIp
        {
            get { return (String)base["InitialAddressIp"]; }
            set { base["InitialAddressIp"] = value; }
        }
        [SettingsAllowAnonymous(false)]
        public String LastAddressIp
        {
            get { return (String)base["LastAddressIp"]; }
            set { base["LastAddressIp"] = value; }
        }
    }
}
